package edu.cuit.avatar.collection;

import java.util.*;

/**
 * Set的实例不包含重复元素
 * @author <a href="mailto:1020zhaodan@163.com">Adan</a>
 * @version 1.0
 * @date 2025/7/15 9:41
 */
public class SetTest {
    /**
     * HashSet底层采用HashMap进行实现
     */
    public static void hashSet(){
        Set<String> set = new HashSet<>();
        set.add("peppa");
        set.add("jorge");
        set.add("peppa");
        set.add("emily");
        set.add("peppa");
        System.out.println(set.size());
        System.out.println(set);
        System.out.println("=======================================");

        Set<Circle> circles = new HashSet<>();
        circles.add(new Circle(5));
        circles.add(new Circle(3));
        circles.add(new Circle(15));
        circles.add(new Circle(20));
        circles.add(new Circle(5));
        circles.add(new Circle(3));

        for(var circle : circles)
            System.out.println(circle);

        System.out.println("==================================");
        Integer[] list1 = {1, 2, 3, 3, 5};
        Integer[] list2 = {1, 2, 3, 3, 4, 5, 6};

        System.out.println(Arrays.toString(joinAndDistinct(list1, list2)));

        var list = new HashSet<Integer>(Arrays.asList(list1));
        list.addAll(Arrays.asList(list2));

        System.out.println(list);

    }

    /**
     * LinkedHashSet---->LinkedHashMap
     * LinkedHashSet用一个链表来扩展HashSet类，它支持对集合内的元素排序。
     *      HashSet中的元素是没有顺序的，而LinkedHashSet中的元素可以按照它们插入集合的顺序提取。
     */
    public static void linkedHashSet(){
        var set = new LinkedHashSet<String>();
        set.add("peppa");
        set.add("jorge");
        set.add("peppa");
        set.add("emily");
        set.add("peppa");
        set.addFirst("Dannie");
        System.out.println(set.size());
        System.out.println(set);
        System.out.println("=======================================");

        Set<Circle> circles = new LinkedHashSet<>();
        circles.add(new Circle(5));
        circles.add(new Circle(3));
        circles.add(new Circle(15));
        circles.add(new Circle(20));
        circles.add(new Circle(5));
        circles.add(new Circle(3));

        for(var circle : circles)
            System.out.println(circle);
    }

    /**
     * TreeSet集合实现了NavigableSet,SortedSet,Set接口。
     * TreeSet可以确保集合中的元素是有序的。默认按照自然顺序(Comparable)进行排序
     * 1.内部采用红黑树实现
     * 2.有序集合
     * 3.元素不重复
     * 4.默认按照自然顺序(Comparable)进行排序,不允许插入null值
     */
    public static void treeSet(){
        Set<String> names = new TreeSet<>();
        names.add("Peppa");
        names.add("Emily");
        names.add("Candy");
        names.add("Dannie");
        //names.add(null);
        names.add("Peppa");

        System.out.println(names);
        System.out.println("===========================");
        //使用比较顺序排序
        var students = new TreeSet<Student>((s1, s2) -> s1.getName().compareTo(s2.getName()));

        students.add(new Student("张三丰", "太极")); //ClassCastException
        students.add(new Student("金毛狮王", "狮吼功"));
        students.add(new Student("张无忌", "乾坤大挪移"));
        students.add(new Student("张翠山", "....."));
        students.add(null);

        for(var student : students)
            System.out.println(student);
    }

    public static void main(String[] args) {
        //hashSet();
        //linkedHashSet();
        treeSet();
    }


    public static Integer[] joinAndDistinct(Integer[] list1, Integer[] list2){
        Integer[] target = new Integer[list1.length + list2.length];
        //将源数组中的元素拷贝进目标数组
        System.arraycopy(list1, 0, target, 0, list1.length);
        System.arraycopy(list2, 0, target, list1.length, list2.length);
        System.out.println("合并后的数组:" + Arrays.toString(target));
        //对目标数组进行排序
        Arrays.sort(target);
        //使用快慢指针算法进行去重
        int slow = 0;
        for(var fast = 1; fast < target.length; fast++){
            if(target[slow] != target[fast]){
                //slow++;
                target[++slow] = target[fast];
            }
        }
        //去掉多余的元素,数组的真实大小: slow + 1
        Integer[] dest = new Integer[slow + 1];
        System.arraycopy(target, 0, dest, 0, dest.length);
        return dest;
    }
}
